﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

namespace HeritageAcademy.Shared
{
    /// <summary>
    /// Encapsulate the IO operations
    /// </summary>
    public static class IOHelper
    {
        #region Constants

        private static readonly string LIBRARY_FOLDER = Properties.Resources.Application_ProductName + " Library";
        private static readonly string METADATA_FOLDER = Properties.Resources.Application_ProductName;

        private const string TESTS_FOLDER = "Tests";
        private const string TESTS_DATAFILE_FILTER = "*.data";

        #endregion

        /// <summary>
        /// Gets the book user metadata folder
        /// </summary>
        public static string CourseUserMetadataFolder
        {
            get
            {
                var applicationDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                var bookUserMetadataFolder = Path.Combine(applicationDataFolder, LIBRARY_FOLDER);

                // make sure folder exists
                if (!Directory.Exists(bookUserMetadataFolder))
                    Directory.CreateDirectory(bookUserMetadataFolder);

                return bookUserMetadataFolder;
            }
        }

        public static string CourseTemporaryFolder
        {
            get
            {
                var tempDataFolder = Path.GetTempPath();
                var bookTemporaryFolder = Path.Combine(tempDataFolder, LIBRARY_FOLDER);

                // make sure folder exists
                if (!Directory.Exists(bookTemporaryFolder))
                {
                    Directory.CreateDirectory(bookTemporaryFolder);
                }

                return bookTemporaryFolder;
            }
        }

        /// <summary>
        /// Gets the default course's search folders
        /// </summary>
        /// <remarks>
        /// Potentially there may be more then single folder
        /// </remarks>
        public static IEnumerable<string> DefaultCoursesFolders
        {
            get
            {
                var myDoc = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                var courseDir = Path.Combine(myDoc, LIBRARY_FOLDER);

                if (!Directory.Exists(courseDir))
                    Directory.CreateDirectory(courseDir);

                return new List<string> {courseDir};
            }
        }

        public static IEnumerable<string> TestDataFilesPaths(string courseTitle)
        {
            var folder = Path.Combine(CourseTemporaryFolder, courseTitle, TESTS_FOLDER);
            return (Directory.Exists(folder)) 
                ? Directory.GetFiles(folder, TESTS_DATAFILE_FILTER, SearchOption.AllDirectories)
                : null;
        }

        public static string CommonMetaDataFolder
        {
            get
            {
                var applicationDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                var metaDataFolder = Path.Combine(applicationDataFolder, METADATA_FOLDER);

                // make sure folder exists
                if (!Directory.Exists(metaDataFolder))
                    Directory.CreateDirectory(metaDataFolder);

                return metaDataFolder;
            }
        }

        public static string CommonFilesFolder
        {
            get
            {
                var commonFilesFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles);
                var commonMetaDataFolder = Path.Combine(commonFilesFolder, METADATA_FOLDER);

                // make sure folder exists
                if (!Directory.Exists(commonMetaDataFolder))
                    Directory.CreateDirectory(commonMetaDataFolder);

                return commonMetaDataFolder;
            }
        }

        public static string ApplicationStartupPath
        {
            get { return Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); }
        }

        public static string ApplicationSourceRootPath
        {
            get { return Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName).Replace(@"bin\Debug", ""); }
        }

        #region Public Methods

        public static string GetFullFilePath(string path, bool mustExist = true)
        {
            var realizedPath = !Path.IsPathRooted(path)
                                   ? Path.Combine(ApplicationStartupPath, path)
                                   : Path.GetFullPath(path);

            return mustExist
                       ? (File.Exists(realizedPath) || Directory.Exists(realizedPath) ? realizedPath : null)
                       : realizedPath;
        }

        public static string ReadFile(string relativeOrAbsolutePath)
        {
            var path = GetFullFilePath(relativeOrAbsolutePath);
            return path != null ? File.ReadAllText(path) : null;
        }

        #endregion Public Methods

        /*
        /// <summary>
        /// Gets whether the current OS is Win 7
        /// </summary>
        /// <returns></returns>
        private static bool IsWin7()
        {
            if (Environment.OSVersion.Version.Major >= 6)
            {
                if (Environment.OSVersion.Version.Minor >= 1) // Win 7
                    return true;
                // vista
            }
            //else if (Environment.OSVersion.Version.Major >= 5) // XP
            //    return false;

            return false;
        }

        public static string ToSafeFileName(this string folderName)
        {
            const char SAFE_CHAR = '_';
            var builder = new StringBuilder(folderName);
            foreach (var c in Path.GetInvalidFileNameChars())
            {
                builder.Replace(c, SAFE_CHAR);
            }
            return builder.ToString();
        }

        public static string ToSafeFolderName(this string folderName)
        {
            const char SAFE_CHAR = '_';
            var dirBulder = new StringBuilder(folderName);
            foreach (var c in Path.GetInvalidPathChars())
            {
                dirBulder.Replace(c, SAFE_CHAR);
            }
            return dirBulder.ToString();
        }
        */
    }
}